package com.pricl.frame.shiro;

import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.pricl.frame.core.App;
import com.pricl.frame.core.User;
import com.pricl.frame.core.web.Helper;

/**
 * 
 * @author cheng(iknoweth@yahoo.com)
 * @date 2016-5-4 下午10:18:51
 */
public class ShiroRealm extends AuthorizingRealm {

	Logger logger = LoggerFactory.getLogger(ShiroRealm.class);

	private App app;

	// @Override
	// public void onLogout(PrincipalCollection principals) {
	// //System.out.println("退出");
	// clearCachedAuthenticationInfo(principals);
	// clearCache(principals);
	// super.onLogout(principals);
	// }

	/**
	 * 授权-url请求调用 配置缓存后只加载一次
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		return app.getInfo(((ShiroUser) super.getAvailablePrincipal(principals)).getUid());
	}

	/**
	 * 验证-登陆时调用
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		String password = String.valueOf(token.getPassword());
		
		if (username == null || username.equals("") || password == null || password.equals("")) {
			throw new AuthenticationException("账号或密码不能为空");
		}

		User user = app.findForLogin(username, password, null);
		if (user != null) {
			ShiroUser shiroUser = new ShiroUser(user.id, user.username, this.getName());
			// // TODO null的处理
			 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
			 Helper.setUser(request.getSession().getId(), user);
			return new SimpleAuthenticationInfo(shiroUser, password, this.getName());
		}
		return null;
	}

	public static DefaultFilterChainManager getDefaultFilterChainManager() {
		return (DefaultFilterChainManager) ((PathMatchingFilterChainResolver) Helper.getBean(AbstractShiroFilter.class)
				.getFilterChainResolver()).getFilterChainManager();
	}

	/**
	 * 初始化shiro拦截器
	 */
	public void initShiroFilterChain() {

		DefaultFilterChainManager filterChainManager = getDefaultFilterChainManager();
		// before
		for (Entry<String, String> item : app.getPrefixPerms().entrySet()) {
			filterChainManager.createChain(item.getKey(), item.getValue());
		}
		// 从数据库载入动态权限
		Map<String, String> modules = app.getDefinePerms();

		if (modules != null && !modules.isEmpty()) {
			for (Entry<String, String> item : modules.entrySet()) {
				//System.out.println(item.getKey() + "::" + item.getValue());
				filterChainManager.createChain(item.getKey(), item.getValue());
			}
		}

		// after
		for (Entry<String, String> item : app.getSuffixPerms().entrySet()) {
			filterChainManager.createChain(item.getKey(), item.getValue());
		}

	}

	public App getApp() {
		return app;
	}

	public void setApp(App app) {
		this.app = app;
	}

}
